package net.cloudcodex.server.data;

import java.util.List;
import java.util.logging.Logger;

import net.cloudcodex.server.Context;
import net.cloudcodex.server.data.Data.Campaign;
import net.cloudcodex.server.data.Data.CharacterNote;
import net.cloudcodex.server.data.Data.Message;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Query.FilterOperator;

/**
 * Generated DAO extension.
 * 
 * @author Thomas
 */
public class AdvancedDAO extends DAO {

	private final Logger logger = Logger.getLogger(AdvancedDAO.class.getName());
	
	public AdvancedDAO(DatastoreService store) {
		super(store);
	}

	/**
	 * Searchs an user by its email.
	 */
	public Data.User getUserByEmail(Context context, String email) {
		return asSingleUser(context, addUserFilterOnEmail(queryUser(), FilterOperator.EQUAL, email));
	}
	
	
	/**
	 * Searchs an user by its google id.
	 */
	public Data.User getUserByGoogleId(Context context, String userId) {
		return asSingleUser(context, addUserFilterOnGoogleId(queryUser(), FilterOperator.EQUAL, userId));
	}

	/**
	 * Searches the campaign's playable characters (owner != null)
	 * @param context execution context.
	 * @param campaignKey campaign's key.
	 * @return list of playable characters of the campaign.
	 */
	public List<Data.Character> getCampaignPlayableCharacters(Context context, Key campaignKey) {
		return asListOfCharacters(context, addCharacterFilterOnOwner(
			queryCharacter(campaignKey), FilterOperator.NOT_EQUAL, null), null);
	}

	/**
	 * Searches the campaign's characters
	 * @param context execution context.
	 * @param campaignKey campaign's key.
	 * @return list of characters of the campaign.
	 */
	public List<Data.Character> getCampaignCharacters(Context context, Key campaignKey) {
		return asListOfCharacters(context, queryCharacter(campaignKey), null);
	}

	/**
	 * Searches the note about a character by another character (or GM).
	 * @param characterKey character's key.
	 * @param authorKey note's author's key or null for GM.
	 * @return the current {@link CharacterNote} or nul if not found.
	 */
	public CharacterNote getCharacterNoteByAuthor(Context context, Key characterKey, Key authorKey) {
		return asSingleCharacterNote(context, addCharacterNoteFilterOnAuthor(
			queryCharacterNote(characterKey), FilterOperator.EQUAL, authorKey));
	}
	

	/**
	 * Searches the message of a scene.
	 * @param sceneKey scene key.
	 * @return the messages.
	 */
	public List<Message> getSceneMessages(Context context, Key sceneKey) {
		return asListOfMessages(context, queryMessage(sceneKey), null);
	}
	
	/**
	 * Searches the character with the given name.
	 */
	public Data.Character getCharacterByName(Context context, Key campaignKey, String name) {
		return asSingleCharacter(context, addCharacterFilterOnName(
			queryCharacter(campaignKey), FilterOperator.EQUAL, name));
	}
	
	/**
	 * Searches the campaign with the given name.
	 */
	public Campaign getCampaignByName(Context context, String name) {
		return asSingleCampaign(context, addCampaignFilterOnName(
			queryCharacter(), FilterOperator.EQUAL, name));
	}

}
